package gui.view.android;

import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JPanel;

import model.MetroModel;
import gui.view.android.graphics.*;
import gui.view.android.graphics.factories.*;

import com.nightpiter.controller.log.AbstractLogger;
import com.nightpiter.controller.log.Logger;
import com.nightpiter.model.objects.Coordinated;
import com.nightpiter.model.objects.Coordinates;
import com.nightpiter.view.Calculator;
import com.nightpiter.view.drawer.rapid.RapidMetroDrawer;
import com.nightpiter.view.drawer.simple.SimpleMetroDrawer;
import com.nightpiter.view.graphics.Canvas;
import com.nightpiter.view.graphics.Point;
import com.nightpiter.view.graphics.PointF;
import com.nightpiter.view.graphics.factories.LinearGradientFactory;
import com.nightpiter.view.graphics.factories.PaintFactory;
import com.nightpiter.view.graphics.factories.PathDashPathEffectFactory;
import com.nightpiter.view.graphics.factories.PathEffectFactory;
import com.nightpiter.view.graphics.factories.PathFactory;
import com.nightpiter.view.graphics.factories.RadialGradientFactory;
import com.nightpiter.view.graphics.factories.RectFFactory;
import com.nightpiter.view.graphics.factories.RectFactory;
import com.nightpiter.view.graphics.factories.ShaderFactory;

public class AndroidDrawerPanel extends JPanel{// extends MetroView{
	
	private float scale = 10f;
	private int xTransform = 0, yTransform = 0;
	private com.nightpiter.view.drawer.MetroDrawer drawer;
	
	public com.nightpiter.view.drawer.MetroDrawer getDrawer() {
		return drawer;
	}
	
	public AndroidDrawerPanel() {
				
		
		PaintFactory.setFactory(new JavaPaintFactory());
		PathDashPathEffectFactory
				.setFactory(new JavaPathDashPathEffectFactory());
		PathEffectFactory.setFactory(new JavaPathEffectFactory());
		PathFactory.setFactory(new JavaPathFactory());
		RectFactory.setFactory(new JavaRectFactory());
		RectFFactory.setFactory(new JavaRectFFactory());
		RadialGradientFactory.setFactory(new JavaRadialGradientFactory());
		ShaderFactory.setFactory(new JavaShaderFactory());
		LinearGradientFactory.setFactory(new JavaLinearGradientFactory());
		
		drawer = AndroidDrawersRegistry.getCurrentDrawer().drawer;
		//c = new com.nightpiter.view.drawer.rapid.RapidMetroDrawer();
		//Logger.log(MetroModel.getInstance().getModelData().getHubs().toString());
		//for(MetroModel.getInstance().get)
		//c.prepare(MetroModel.getInstance().getModelData(), com.nightpiter.view.Calculator.Mode.POSITION);

	}
	public void paintComponent(Graphics g) {
		super.paintComponent(g);		
		if(drawer==null) {
			drawer=AndroidDrawersRegistry.getDrawers().get(0).drawer;
		}
		if(drawer==null) {return;}
		Canvas canvas = JavaCanvas.wrap((Graphics2D)g);		
		//((Graphics2D)g).scale(scale, scale);
		((Graphics2D)g).translate(xTransform, yTransform);
		//drawer.prepare(MetroModel.getInstance().getModelData(), com.nightpiter.view.Calculator.Mode.POSITION);
		drawer.drawMetro(canvas, calculator);
	}
	
	public void shift(int dx, int dy) {
		xTransform+=dx;
		yTransform+=dy;
	}
	
	public void reset() {
		xTransform=0;
		yTransform=0;
	}
	public void setScale(float scale) {
		this.scale = scale;
	}
	
	public float getScale(){
		return scale;
	}
	
	public void updateModel() {
		if(drawer!=null) drawer.prepare(MetroModel.getInstance().getModelData(), com.nightpiter.view.Calculator.Mode.POSITION);
	}
	public void setCenter(int x, int y) {
		xTransform = x;
		yTransform = y;
		
	}
	public Point getCenter() {
		return new Point(xTransform,yTransform);
		
	}
	
	private EditorCalc calculator = new EditorCalc();
	private class EditorCalc extends Calculator {

		private float offsetX = 0, offsetY = 0;

		public void scale(float s) {
			scale = s;
		}

		private void offset(float dx, float dy) {
			offsetX += dx / scale;
			offsetY += dy / scale;
		}

		@Override
		public Mode getMode() {
			return Mode.POSITION;
		}

		@Override
		public void convert(Coordinates coordinates, PointF pointF) {
			pointF.x = (coordinates.x + offsetX) * scale;
			pointF.y = (coordinates.y + offsetY) * scale;
		}

		@Override
		public void convert(Coordinates coordinates, Point point) {
			point.x = (int) ((coordinates.x + offsetX) * scale);
			point.y = (int) ((coordinates.y + offsetY) * scale);
		}

		@Override
		public void convert(Coordinated coordinated, PointF pointF) {
			convert(coordinated.getPosition(), pointF);
		}

		@Override
		public void convert(Coordinated coordinated, Point point) {
			convert(coordinated.getPosition(), point);
		}

		@Override
		public void convert(PointF coordF, PointF pointF) {
			pointF.x = (coordF.x + offsetX) * scale;
			pointF.y = (coordF.y + offsetY) * scale;
		}

		@Override
		public void convert(PointF coordF, Point point) {
			point.x = (int) ((coordF.x + offsetX) * scale);
			point.y = (int) ((coordF.x + offsetX) * scale);
		}

		@Override
		public void revert(Point point, PointF coordF) {
			coordF.x = (point.x) / scale - offsetX;
			coordF.y = (point.y) / scale - offsetY;
		}

		@Override
		public void revert(PointF pointF, PointF coordF) {
			coordF.x = (pointF.x) / scale - offsetX;
			coordF.y = (pointF.y) / scale - offsetY;
		}

		@Override
		public Coordinates getCoordinates(Coordinated coordinated) {
			return coordinated.getPosition();
		}

	};
	
	public void setDrawer(com.nightpiter.view.drawer.MetroDrawer drawer) {
		this.drawer = drawer;
		drawer.prepare(MetroModel.getInstance().getModelData(), com.nightpiter.view.Calculator.Mode.POSITION);
		this.repaint();
	}
	
	

}
